package com.example.event_resource_java.authority.server.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.event_resource_java.authority.dao.CourseClassDao.StuClassDO;
import com.example.event_resource_java.authority.dao.*;
import com.example.event_resource_java.authority.dao.PaperDao.*;
import com.example.event_resource_java.authority.mapper.*;
import com.example.event_resource_java.authority.server.ErrorBookService;
import com.example.event_resource_java.authority.server.ResourceServer;
import com.example.event_resource_java.authority.server.UserServer;
import com.example.event_resource_java.commons.domain.UserDO;
import com.example.event_resource_java.commons.enums.Constants;
import com.example.event_resource_java.commons.enums.EnumErrorCode;
import com.example.event_resource_java.commons.model.CaseBody;
import com.example.event_resource_java.commons.model.ItemIdOptionBody;
import com.example.event_resource_java.commons.model.PracticeRecordBody;
import com.example.event_resource_java.commons.model.TheoreticalBody;
import com.example.event_resource_java.commons.util.ApiResult;
import com.example.event_resource_java.commons.util.DateUtils;
import com.example.event_resource_java.commons.util.JWTUtil;
import com.example.event_resource_java.commons.vo.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ResourceServerImpl
 * @Description:
 * @Author: ak
 * @CreateDate: 2024/4/11 17:28
 * @UpdateUser:
 * @UpdateDate: 2024/4/11 17:28
 * @UpdateRemark:
 * @Version: 1.0
 */
@Service
public class ResourceServerImpl extends ServiceImpl<ResourceMapper, EventResourceAllocationsDO> implements ResourceServer {

    @Resource
    private ResourceMapper resourceMapper;
    @Resource
    private ClassMapper classMapper;
    @Resource
    private UserServer userServer;
    @Resource
    private StatisticMapper statisticMapper;
    @Resource
    private TemplateCertificateMapper templateCertificateMapper;
    @Resource
    private TemplateDetailsMapper templateDetailsMapper;
    @Resource
    private ErrorBookService errorBookService;
    @Resource
    private TestPaperTemplateMapper testPaperTemplateMapper;
    @Resource
    private PracticeRecordMapper practiceRecordMapper;

    @Override
    public List<String> getHeadLineTitle() {
        return resourceMapper.getHeadLineTitle();
    }

    @Override
    public List<HomeResourceVO> getHomeResourceList() {
        List<EventResourceAllocationDO> allocationList = resourceMapper.getAllocationList();
        List<ModuleDao> moduleList = resourceMapper.getModuleList();

        // 首页资源总概
        ArrayList<HomeResourceVO> homeResourceVOList = new ArrayList<>();

        for (ModuleDao moduleDao : moduleList) {
            Long moduleId = moduleDao.getId();
            HashSet<String> titleList = new HashSet<>();
            HomeResourceVO homeResourceVO = new HomeResourceVO();
            BeanUtils.copyProperties(moduleDao, homeResourceVO);

            ArrayList<EventResourceAllocationDO> allocationDOS = new ArrayList<>();
            for (EventResourceAllocationDO allocationDO : allocationList) {
                Long jzEveMoId = allocationDO.getJzEveMoId();
                if (moduleId.equals(jzEveMoId)) {
                    titleList.add(allocationDO.getEventTitle());
                    allocationDOS.add(allocationDO);
                }
            }
            homeResourceVO.setResourceList(allocationDOS);
            homeResourceVO.setTitleList(titleList);
            homeResourceVOList.add(homeResourceVO);
        }

        for (HomeResourceVO homeResourceVO : homeResourceVOList) {
            List<EventResourceAllocationDO> limit = homeResourceVO.getResourceList().stream()
                    .limit(4).collect(Collectors.toList());
            homeResourceVO.setResourceList(limit);
        }
        // 根据优先级排序
        List<HomeResourceVO> res = homeResourceVOList.stream().sorted(Comparator.comparing(HomeResourceVO::getType)).collect(Collectors.toList());
        return res;
    }

    @Override
    public PageResult homeSearch(String searchValue, Integer pageNum, Integer pageSize) {
        // 根据优先级遍历资源
        // 赛项资源allocations 课程资源 1+x证书 技能培训  行业资源

        // 赛项资源 allocations中模糊匹配 左连接allocation 返回allocationName allocationsName allocationsCreateTime
        PageHelper.startPage(pageNum, pageSize);
        List<HomeSearchVO> homeSearch = resourceMapper.getHomeSearch(searchValue);

        PageInfo<HomeSearchVO> pageInfo = new PageInfo<>(homeSearch);
        Page<HomeSearchVO> page = (Page<HomeSearchVO>) homeSearch;

        return new PageResult(pageInfo.getTotal(), page.getResult());
    }

    @Override
    public List<ModuleDao> getModuleList() {
        return resourceMapper.getModuleList();
    }

    @Override
    public MatchRequestVO getMatchRequestParam(String eveMoId) {

        // 获取模块内所有资源
        List<EventResourceAllocationDO> allocationList = resourceMapper.getEventTitle(Long.valueOf(eveMoId));

        // 赛项资源 产品需求改名
        List<String> eventTitleList = allocationList.stream()
                .map(EventResourceAllocationDO::getEventTitle)
                .distinct()
                .collect(Collectors.toList());
        ArrayList<String> sortedTitle = new ArrayList<>();
        sortedTitle.addAll(eventTitleList);
        if (ObjectUtil.equal(eveMoId, "1775402446075265026")) {
            sortedTitle.remove("产后恢复");
            sortedTitle.remove("幼儿照护");
            if (eventTitleList.contains("幼儿照护")) {
                sortedTitle.add("幼儿照护(金砖)");
            }
            if (eventTitleList.contains("产后恢复")) {
                sortedTitle.add("产后恢复(金砖)");
            }
        }


        List<Integer> list = allocationList.stream()
                .map(EventResourceAllocationDO::getEventType)
                .distinct()
                .collect(Collectors.toList());

        HashMap<Integer, String> eventTypeMap = new HashMap<>();
        for (Integer i : list) {
            if (i == 0) {
                eventTypeMap.put(0, Constants.NATIONAL_MATCH);
            } else if (i == 1) {
                eventTypeMap.put(1, Constants.PROVINCE_MATCH);
            } else if (i == 2) {
                eventTypeMap.put(2, Constants.CITY_MATCH);
            }
        }

        // 返回从2020年到今年年份列表
        ArrayList<String> createTimeList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        for (int i = 2020; i <= calendar.get(Calendar.YEAR); i++) {
            createTimeList.add(String.valueOf(i));
        }


        return new MatchRequestVO(sortedTitle, eventTypeMap, createTimeList);
    }


    @Override
    public PageResult getMatchResourceList(String eventName, Integer type, String time, Integer grade, Long evenMoId,
                                           Integer pageNum, Integer pageSize) {
        // 分页
        PageHelper.startPage(pageNum, pageSize);
        List<EventResourceAllocationDO> matchResourceList = resourceMapper.getMatchResourceList(eventName, type, time, evenMoId, grade);
        Page<EventResourceAllocationDO> resourcePage = (Page<EventResourceAllocationDO>) matchResourceList;

        return new PageResult(resourcePage.getTotal(), resourcePage.getResult());
    }


    @Override
    public ApiResult getMatchResourceDetails(Long id) {
        // 增加学习人次
        resourceMapper.updateNumStu(id);
        // 所有子资源
        List<EventResourceAllocationsDO> matchResourceDetailList = resourceMapper.getMatchResourceDetails(id);

        // 获取当前资源信息
        EventResourceAllocationDO allocationDO = resourceMapper.getAllocationById(id);

        // 根据type 分类返回
        ArrayList<ExaminationListVO> theoryList = new ArrayList<>();
        ArrayList<EventResourceAllocationsDO> caseList = new ArrayList<>();
        ArrayList<EventResourceAllocationsDO> imitateList = new ArrayList<>();
        ArrayList<EventResourceAllocationsDO> refereeList = new ArrayList<>();
        ArrayList<EventResourceAllocationsDO> practicalMaterialLis = new ArrayList<>();
        ArrayList<EventResourceAllocationsDO> interpretList = new ArrayList<>();

        for (EventResourceAllocationsDO eventResourceAllocationsDO : matchResourceDetailList) {
            Integer type = eventResourceAllocationsDO.getType();
            // 0规程解读 1理论题库 2案例分析题 3模拟赛场 4裁判点评 5实操技能分析 6实操赛项视频 7实操物料清单
            switch (type) {
                case 0:
                    interpretList.add(eventResourceAllocationsDO);
                    break;
                case 1: {
                    // 获取理论题库
                    getTheoretical2(theoryList, eventResourceAllocationsDO);
                    break;
                }
                case 2:
                    // 案例分析
                    caseList.add(eventResourceAllocationsDO);
                    break;
                case 3:
                    // 模拟赛场
                    imitateList.add(eventResourceAllocationsDO);
                    break;
                case 4:
                    // 裁判点评
                    refereeList.add(eventResourceAllocationsDO);
                    break;
//                case 5:
//                    // 实操技能分析
//                    practicalSkillList.add(eventResourceAllocationsDO);
//                    break;
//                case 6:
//                    // 实操赛项 tree
//                    practicalMatchList.add(eventResourceAllocationsDO);
//                    break;
                case 7:
                    // 实操物料
                    practicalMaterialLis.add(eventResourceAllocationsDO);
                    break;
            }
        }

        // 赛项视频 目录
        List<EventResourceAllocationsDO> matchList = matchResourceDetailList.stream()
                .filter(e -> e.getType() == 6).collect(Collectors.toList());
        List<EventResourceAllocationsDO> practicalMatchList = getCarTreeList(matchList, allocationDO.getId());

        // 技能分析 目录
        List<EventResourceAllocationsDO> skillList = matchResourceDetailList.stream()
                .filter(e -> e.getType() == 5).collect(Collectors.toList());
        //行业资源逆序
        if (ObjectUtil.equal(allocationDO.getJzEveMoId(), Constants.EVENTMOID_SECTOR)) {
           skillList = skillList.stream().sorted(Comparator.comparing(EventResourceAllocationsDO::getCreateTime,
                    Comparator.nullsFirst(Comparator.naturalOrder())).reversed()).collect(Collectors.toList());
        }
        List<EventResourceAllocationsDO> practicalSkillList = getCarTreeList(skillList, allocationDO.getId());

        // PDF前排序
        List<EventResourceAllocationsDO> sortedInterpret = interpretList.stream()
                .sorted(Comparator.comparing(EventResourceAllocationsDO::getFileUrl).reversed()).collect(Collectors.toList());

        // 非1+x资源分组
        if (ObjectUtil.notEqual(allocationDO.getJzEveMoId(), Constants.EVENTMOID_ONEPLUSXCERTIFICATES)) {
            //裁判点评 实操赛项 实操物料清单根据module分组
            Map<String, List<EventResourceAllocationsDO>> refereeMap = refereeList.stream()
                    .collect(Collectors.groupingBy(EventResourceAllocationsDO::getModule));

            Map<String, List<EventResourceAllocationsDO>> materialMap = practicalMaterialLis.stream()
                    .collect(Collectors.groupingBy(EventResourceAllocationsDO::getModule));

            Map<String, List<EventResourceAllocationsDO>> matchMap = practicalMatchList.stream()
                    .collect(Collectors.groupingBy(EventResourceAllocationsDO::getModule));

            MatchResourceDetailVO matchResourceDetailVO = new MatchResourceDetailVO(allocationDO.getId(), allocationDO.getEventTitle(), allocationDO.getNumStus(),
                    allocationDO.getIntroduce(), allocationDO.getCreateTime(), allocationDO.getImg(), allocationDO.getEventName(), sortedInterpret, theoryList, caseList, imitateList,
                    refereeMap, practicalSkillList, matchMap, materialMap);


            return ApiResult.success(matchResourceDetailVO);
        }

        // 证书标准目录
        List<EventResourceAllocationsDO> interpretTree = getCarTreeList(sortedInterpret, allocationDO.getId());
        // 模拟考场目录
        List<EventResourceAllocationsDO> imitateTree = getCarTreeList(imitateList, allocationDO.getId());
        // 课程标准
        List<EventResourceAllocationsDO> caseTree = getCarTreeList(caseList, allocationDO.getId());
        // 考评标准
        List<EventResourceAllocationsDO> refreenceTree = getCarTreeList(refereeList, allocationDO.getId());

        OnePlusXVO onePlusXVO = new OnePlusXVO(allocationDO.getId(), allocationDO.getEventTitle(), allocationDO.getNumStus(),
                allocationDO.getCreateTime(), interpretTree, theoryList, caseTree, imitateTree,
                refreenceTree, practicalSkillList, practicalMatchList, practicalMaterialLis);
        return ApiResult.success(onePlusXVO);

    }

    @Override
    public Map<String, List<EventResourceAllocationsDO>> getChildren(Long parenId) {
        List<EventResourceAllocationsDO> list = resourceMapper.getMatchResourceByParentId(parenId);
        Map<String, List<EventResourceAllocationsDO>> map = list.stream()
                .collect(Collectors.groupingBy(EventResourceAllocationsDO::getModule));
        return map;
    }

    // 理论题库 单独获取
    private void getTheoretical(ArrayList<ExaminationListVO> theoryList, EventResourceAllocationsDO eventResourceAllocationsDO) {
        CertificateNewsDO certificateNews = resourceMapper.getCertificateNews(eventResourceAllocationsDO.getPaperModule());

        List<ExaminationListDO> examinationList = resourceMapper.getExaminationList(certificateNews.getProfileId());
        if (ObjectUtil.isNull(examinationList)) {
            return;
        }

        for (ExaminationListDO examinationListDO : examinationList) {
            if (examinationListDO.getTemplateId().equals(eventResourceAllocationsDO.getPaperModule())) {
                ExaminationListVO examinationListVO = new ExaminationListVO();
                BeanUtils.copyProperties(examinationListDO, examinationListVO);
                examinationListVO.setTitle(eventResourceAllocationsDO.getTitle());
                examinationListVO.setTemplateId(examinationListDO.getTemplateId());
                examinationListVO.setNums(eventResourceAllocationsDO.getNums());

                // 判断是否存在未做完练习记录
                Long userId = JWTUtil.getUser().getId();
                Long practiceRecordId = resourceMapper.isExistRecord(userId, examinationListDO.getTemplateId(), examinationListDO.getGrade(), eventResourceAllocationsDO.getParentId());
                if (ObjectUtil.isNotNull(practiceRecordId)) {
                    examinationListVO.setPracticeRecordId(practiceRecordId);
                }

                if (examinationListDO.getTemplateType() == 0) {
                    examinationListVO.setTemplateType("理论考试");
                } else if (examinationListDO.getTemplateType() == 1) {
                    examinationListVO.setTemplateType("技能考试");
                }
                // 判断试卷等级 2 初级 1 中级 0 高级
                if (examinationListDO.getGrade() == 2) {
                    examinationListVO.setGrade(Constants.THEORETICAL_GRADE_TYPE_JUNIOR);
                } else if (examinationListDO.getGrade() == 1) {
                    examinationListVO.setGrade(Constants.THEORETICAL_GRADE_TYPE_MIDDLE);
                } else if (examinationListDO.getGrade() == 0) {
                    examinationListVO.setGrade(Constants.THEORETICAL_GRADE_TYPE_HIGH);
                }
                theoryList.add(examinationListVO);
            }
        }
    }

    private void getTheoretical2(ArrayList<ExaminationListVO> theoryList, EventResourceAllocationsDO eventResourceAllocationsDO) {
        // 根据试卷模板id获取关联表知识点
        List<TemplateCertificateDO> templateCertificateDOList = templateCertificateMapper.selectList(new QueryWrapper<TemplateCertificateDO>()
                .eq("paper_template_id", eventResourceAllocationsDO.getPaperModule()));

        if (ObjectUtil.isNull(templateCertificateDOList)) {
            return;
        }

        ExaminationListVO examinationListVO = new ExaminationListVO();
        examinationListVO.setTemplateType("理论考试");
        // 查询模板信息
        TestPaperTemplateDO testPaperTemplateDO = testPaperTemplateMapper.selectById(eventResourceAllocationsDO.getPaperModule());
        examinationListVO.setDuration(testPaperTemplateDO.getDuration());
        examinationListVO.setTemplateId(eventResourceAllocationsDO.getPaperModule());
        examinationListVO.setTitle(eventResourceAllocationsDO.getTitle());
        examinationListVO.setGroupType(eventResourceAllocationsDO.getGroupType());
        examinationListVO.setType(eventResourceAllocationsDO.getType());

        // 判断是否存在未做完练习记录
        // TODO 去除继续练习
//        if (Objects.nonNull(JWTUtil.getRequest().getHeader("Authorization"))) {
//            Long userId = JWTUtil.getUser().getId();
//            PracticeRecordDO practiceRecordDO = practiceRecordMapper.selectOne(new QueryWrapper<PracticeRecordDO>().eq("user_id", userId)
//                    .eq("paper_id", eventResourceAllocationsDO.getPaperModule())
//                    .eq("state", 0)
//                    .eq("allocation_id", eventResourceAllocationsDO.getParentId()));
//            if (ObjectUtil.isNotNull(practiceRecordDO)) {
//                examinationListVO.setPracticeRecordId(practiceRecordDO.getId());
//            }
            theoryList.add(examinationListVO);
//        }
    }

    //  返回结构
    private static List<EventResourceAllocationsDO> getCarTreeList(List<EventResourceAllocationsDO> parentSonVos, Long topParentId) {
        Integer level = 0;
        if (ObjectUtil.isNotEmpty(parentSonVos)) {
            // 递归获取菜单树形结构
            // 获取父节点，说明：父节点的parentId都是allocationId
            // 排序
            List<EventResourceAllocationsDO> collect = parentSonVos.stream().sorted(Comparator
                            .comparing(EventResourceAllocationsDO::getNodeType).reversed())
                    .collect(Collectors.toList());

            return collect.stream()
                    .filter(p -> ObjectUtil.equal(p.getParentId(), topParentId))
                    .peek(p -> p.setChildrenList(getChildrenCarAttr(p, parentSonVos, level))
                    ).collect(Collectors.toList());
        }

        return Collections.emptyList();
    }

    // 构建树形结构
    private static List<EventResourceAllocationsDO> getChildrenCarAttr(EventResourceAllocationsDO brandSeriesVo, List<EventResourceAllocationsDO> allCarBrandSeriesVos, Integer level) {
        // 子节点parentId = 父节点ID
        level += 1;
        brandSeriesVo.setLevel(level);
        Integer finalLevel = level;
        List<EventResourceAllocationsDO> collect = allCarBrandSeriesVos.stream().sorted(Comparator
                        .comparing(EventResourceAllocationsDO::getNodeType).reversed())
                .collect(Collectors.toList());
        return collect.stream()
                .filter(p -> ObjectUtil.equal(brandSeriesVo.getId(), p.getParentId()))
                .peek(p -> p.setChildrenList(getChildrenCarAttr(p, allCarBrandSeriesVos, finalLevel)))
                .collect(Collectors.toList());
    }

    /**
     * @auther: ak
     * @Description 生成答题试卷
     * @param:
     * @return:
     * @date: 2024/5/6 8:32
     */
    @Override
    public ApiResult getExamination(TheoreticalBody theoreticalBody) {

        ApiResult<Object> result = continueExamJudge(theoreticalBody);
        if (result != null) return result;

        CertificateNewsDO certificateNews = resourceMapper.getCertificateNews(theoreticalBody.getTemplateId());
        TestPaperTemplateDO templateDO = resourceMapper.getTestPaperTemplateDetail(theoreticalBody.getTemplateId());
        String duration = templateDO.getDuration() + ".00";

        ArrayList<ExaminationQuestionVO> single = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> multiple = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> judge = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> practical = new ArrayList<>();

        // 根据试卷模板id 获取试卷模板profileId  type
        List<TemplateDetailsDO> templateDetailList =
                resourceMapper.getTemplateDetail(theoreticalBody.getTemplateId(), theoreticalBody.getTemplateType());
        // 根据模板获取各类型题目数量
        ArrayList<ItemIdOptionBody> itemIdOptionBodies = new ArrayList<>();
        for (TemplateDetailsDO templateDetailsDO : templateDetailList) {
            Integer topicType = templateDetailsDO.getType();
            // 题目类型为练习题
            List<ItemBankDO> examination = resourceMapper.getExamination(certificateNews.getProfileId(), theoreticalBody.getGrade(),
                    theoreticalBody.getItemBankType(), theoreticalBody.getTemplateType(), topicType, templateDetailsDO.getTitleNumber());

            // 转换
            ArrayList<ExaminationQuestionVO> questionList = new ArrayList<>();
            for (ItemBankDO itemBankDO : examination) {
                ExaminationQuestionVO examinationQuestionVO = new ExaminationQuestionVO();
                BeanUtils.copyProperties(itemBankDO, examinationQuestionVO);
                questionList.add(examinationQuestionVO);
                itemIdOptionBodies.add(new ItemIdOptionBody(itemBankDO.getId(), ""));
            }
            // 存储题目
            if (0 == templateDetailsDO.getType()) {
                single.addAll(questionList);
            } else if (1 == templateDetailsDO.getType()) {
                multiple.addAll(questionList);
            } else if (2 == templateDetailsDO.getType()) {
                judge.addAll(questionList);
            } else if (3 == templateDetailsDO.getType()) {
                practical.addAll(questionList);
            }
        }

        Long userId = JWTUtil.getUser().getId();
        Long practiceId = null;

        EventResourcePracticeRecordDO practiceRecordDO = new EventResourcePracticeRecordDO();
        practiceRecordDO.setPaperTitle(theoreticalBody.getTemplateName());
        // TODO 老师不记录
        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.eq("id", userId);
        UserDO one = userServer.getOne(userDOQueryWrapper);

        if (one.getType() == 0) {
            // 存储题目集合到练习记录
            // templateId userId classId paperTitle studentName completeNum latestPracticeTime score level answerList
            // 获取学生班级
            StuClassDO stuClassDO = classMapper.getUserClassId(userId);
            practiceRecordDO.setTemplateId(theoreticalBody.getTemplateId());
            practiceRecordDO.setLatestPracticeTime(DateUtils.getTime());
            practiceRecordDO.setCompleteNum(0);
            practiceRecordDO.setUserId(userId);
            practiceRecordDO.setPaperTitle(theoreticalBody.getTemplateName());
            practiceRecordDO.setState(0);
            practiceRecordDO.setClassId(stuClassDO.getClassId());

            if (Constants.SYS_USER_ROLE_TEACHER.equals(stuClassDO.getType())) {
                practiceRecordDO.setStudentName(JWTUtil.getUser().getName());
            } else {
                practiceRecordDO.setStudentName(stuClassDO.getName());
            }

            practiceRecordDO.setExaminationTime(duration);
            // 练习集合 转json存储
            practiceRecordDO.setAnswerList(JSON.toJSONString(itemIdOptionBodies));

            if (Constants.THEORETICAL_GRADE_TYPE_JUNIOR.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(2);
            } else if (Constants.THEORETICAL_GRADE_TYPE_MIDDLE.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(1);
            } else if (Constants.THEORETICAL_GRADE_TYPE_HIGH.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(0);
            }
            // 存储练习
            Long aLong = resourceMapper.savePracticeRecord(practiceRecordDO);
            practiceId = practiceRecordDO.getId();
        }

        PaperDetailVo paperDetailVo = new PaperDetailVo(practiceId, practiceRecordDO.getPaperTitle(),
                duration, single, multiple, judge, practical);
        return ApiResult.success(paperDetailVo);
    }

    /**
     * 生成在线练习试卷 开始练习
     *
     * @param theoreticalBody
     * @return
     */
    @Override
    public ApiResult getExamination2(TheoreticalBody theoreticalBody) {

        // TODO 去除继续练习
//        ApiResult<Object> result = continueExamJudge(theoreticalBody);
//        if (result != null) return result;

//        CertificateNewsDO certificateNews = resourceMapper.getCertificateNews(theoreticalBody.getTemplateId());
        TestPaperTemplateDO templateDO = resourceMapper.getTestPaperTemplateDetail(theoreticalBody.getTemplateId());
        String duration = templateDO.getDuration() + ".00";

        ArrayList<ExaminationQuestionVO> single = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> multiple = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> judge = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> practical = new ArrayList<>();

        // 根据试卷模板id 获取试卷模板profileId  type
//        List<TemplateDetailsDO> templateDetailList =
//                resourceMapper.getTemplateDetail(theoreticalBody.getTemplateId(), theoreticalBody.getTemplateType());
        // 根据模板获取各类型题目数量
        ArrayList<ItemIdOptionBody> itemIdOptionBodies = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> questionList = new ArrayList<>();

        List<ItemBankDO> examQuestion = getExamQuestion(theoreticalBody);
        for (ItemBankDO itemBankDO : examQuestion) {
            ExaminationQuestionVO examinationQuestionVO = new ExaminationQuestionVO();
            BeanUtils.copyProperties(itemBankDO, examinationQuestionVO);
            questionList.add(examinationQuestionVO);
            // 题目集合 TODO
            itemIdOptionBodies.add(new ItemIdOptionBody(itemBankDO.getId(), ""));

            // 存储题目
            if (0 == itemBankDO.getTopicTypes()) {
                single.add(examinationQuestionVO);
            } else if (1 == itemBankDO.getTopicTypes()) {
                multiple.add(examinationQuestionVO);
            } else if (2 == itemBankDO.getTopicTypes()) {
                judge.add(examinationQuestionVO);
            } else if (3 == itemBankDO.getTopicTypes()) {
                practical.add(examinationQuestionVO);
            }
        }

        Long userId = JWTUtil.getUser().getId();
        Long practiceId = null;

        EventResourcePracticeRecordDO practiceRecordDO = new EventResourcePracticeRecordDO();
        practiceRecordDO.setPaperTitle(theoreticalBody.getTemplateName());
        practiceRecordDO.setAllocationId(theoreticalBody.getAllocationId());

        // 老师不记录
        UserDO one = userServer.getById(userId);
        if (one.getType() == 0) {
            // 存储题目集合到练习记录
            // templateId userId classId paperTitle studentName completeNum latestPracticeTime score level answerList
            // 获取学生班级
            StuClassDO stuClassDO = classMapper.getUserClassId(userId);
            practiceRecordDO.setTemplateId(theoreticalBody.getTemplateId());
            practiceRecordDO.setLatestPracticeTime(DateUtils.getTime());
            practiceRecordDO.setCompleteNum(0);
            practiceRecordDO.setUserId(userId);
            practiceRecordDO.setPaperTitle(theoreticalBody.getTemplateName());
            practiceRecordDO.setState(0);
            practiceRecordDO.setClassId(stuClassDO.getClassId());

            if (Constants.SYS_USER_ROLE_TEACHER.equals(stuClassDO.getType())) {
                practiceRecordDO.setStudentName(JWTUtil.getUser().getName());
            } else {
                practiceRecordDO.setStudentName(stuClassDO.getName());
            }

            practiceRecordDO.setExaminationTime(duration);
            // 练习集合 转json存储
            practiceRecordDO.setAnswerList(JSON.toJSONString(itemIdOptionBodies));

            if (Constants.THEORETICAL_GRADE_TYPE_JUNIOR.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(2);
            } else if (Constants.THEORETICAL_GRADE_TYPE_MIDDLE.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(1);
            } else if (Constants.THEORETICAL_GRADE_TYPE_HIGH.equals(theoreticalBody.getGrade())) {
                practiceRecordDO.setLevel(0);
            }
            // 存储练习
            Long aLong = resourceMapper.savePracticeRecord(practiceRecordDO);
            practiceId = practiceRecordDO.getId();
        }

        PaperDetailVo paperDetailVo = new PaperDetailVo(practiceId, practiceRecordDO.getPaperTitle(),
                duration, single, multiple, judge, practical);
        return ApiResult.success(paperDetailVo);
    }

    /**
     * 继续练习判断
     * @param theoreticalBody
     * @return
     */
    private ApiResult<Object> continueExamJudge(TheoreticalBody theoreticalBody) {
        UserDO user = JWTUtil.getUser();
        UserDO userDO = userServer.getById(user.getId());

        if (userDO.getType() == 0) {
            StuClassDO userClassId = classMapper.getUserClassId(user.getId());
            System.out.println(theoreticalBody.getTemplateId());
            System.out.println(userClassId.getClassId());
            System.out.println(user.getId());

            Long practiceRecordId = statisticMapper.PracticeRecordId(theoreticalBody.getTemplateId(),
                    userClassId.getClassId(), user.getId(), theoreticalBody.getAllocationId());
            if (practiceRecordId != null) {
                ApiResult<Object> result = new ApiResult<>();
                result.setCode(EnumErrorCode.duplicateKeyExist.getCode());
                result.setMsg(EnumErrorCode.duplicateKeyExist.getMsg());
                return result;
            }
        }
        return null;
    }

    public List<ItemBankDO> getExamQuestion(TheoreticalBody theoreticalBody) {
        // 试卷模板详情 各类型题目数量 分数
        QueryWrapper<TemplateDetailsDO> templateDetailsDOQueryWrapper = new QueryWrapper<>();
        templateDetailsDOQueryWrapper.eq("tptemplate_id", theoreticalBody.getTemplateId());
        List<TemplateDetailsDO> templateDetailsDOList = templateDetailsMapper.selectList(templateDetailsDOQueryWrapper);

        // 模板详情获取知识点id 获取题目
        ArrayList<ItemBankDO> itemBankDOList = new ArrayList<>();
        for (TemplateDetailsDO t : templateDetailsDOList) {
            Integer itemType = t.getType();
            Long kpointsId = t.getKpointsId();
            Integer titleNumber = t.getTitleNumber();
            // 随机抽取titleNumber道题目 kpointsId itemBankType题库类型 type 类型(理论 技能) topicTypes题目类型 itemNum题目数量
            List<ItemBankDO> itemList = resourceMapper.getItemList(kpointsId, theoreticalBody.getTemplateType(),
                    theoreticalBody.getItemBankType(), itemType, titleNumber);
            itemBankDOList.addAll(itemList);
        }
        // 组装试卷
        return itemBankDOList.stream().distinct().collect(Collectors.toList());

    }

    /**
     * @auther: ak
     * @Description 用户点击交卷
     * @param:
     * @return:
     * @date: 2024/4/29 14:55
     */
    @Override
    public ExamPaperVO submitPaper(PracticeRecordBody practiceRecordBody) {

        UserDO user = JWTUtil.getUser();
        Long userId = user.getId();
        String name = user.getName();

        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.eq("id", userId);
        UserDO one = userServer.getOne(userDOQueryWrapper);

        Long classId = 0L;
        if (one.getType() == 0) {
            // 根据用户id获取 班级id
            classId = classMapper.getUserClassId(userId).getClassId();
        } else {
            classId = null;
        }

        int score = 0;
        ArrayList<ItemPaperDao> singleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> multipleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> judgeQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> practicalQuestionList = new ArrayList<>();
        PracticeRecordDO practiceRecordDO = new PracticeRecordDO();
        practiceRecordDO.setId(practiceRecordBody.getPracticeRecordId());

        // 练习记录
        PracticeRecordDO practiceRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());

        //解析已做题目集合 String 转List
        JSONArray answerJson = JSON.parseArray(practiceRecordBody.getQuestionAnswerList());
        List<ItemIdOptionBody> questionDoneList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);

        // 总题目集合 questionALLList   已做题目集合 questionVOList
        String allQuestionList = practiceRecord.getQuestionAnswerList();
        List<ItemIdOptionBody> questionAllList = JSONArray.parseArray((JSON.parseArray(allQuestionList)).toJSONString(), ItemIdOptionBody.class);

        String examTime = DateUtils.getHourMinuteSecond(practiceRecordBody.getExaminationTime());
        // 用户答题集合不为为空
        if (ObjectUtil.isNotEmpty(questionDoneList)) {
            int single = 0, multiple = 0, judge = 0, practical = 0;
            // 获取各题目分值
            List<TemplateDetailsDO> templateDetailList = resourceMapper.getTemplateDetail(practiceRecord.getPaperId(),
                    0);
            for (TemplateDetailsDO templateDetailsDO : templateDetailList) {
                // 获取总题目数量
                if (0 == templateDetailsDO.getType()) {
                    single = templateDetailsDO.getScore();
                } else if (1 == templateDetailsDO.getType()) {
                    multiple = templateDetailsDO.getScore();
                } else if (2 == templateDetailsDO.getType()) {
                    judge = templateDetailsDO.getScore();
                } else if (3 == templateDetailsDO.getType()) {
                    practical = templateDetailsDO.getScore();
                }
            }

            // 练习记录字段
            BeanUtils.copyProperties(practiceRecordBody, practiceRecordDO);
            practiceRecordDO.setPaperId(practiceRecordBody.getPaperId());
            practiceRecordDO.setClassId(classId);
            practiceRecordDO.setUserId(userId);
            practiceRecordDO.setStudentName(name);
            practiceRecordDO.setLatestPracticeTime(DateUtils.getTime());
            practiceRecordDO.setExaminationTime(examTime);

            // 遍历总题目集合 返回试卷题目答案 计算分值 先小后大
            for (ItemIdOptionBody allItemBody : questionAllList) {
                Long allItemBodyId = allItemBody.getId();
                // 获取题目详情
                ItemPaperDao itemPaperDao = resourceMapper.questionDetail(allItemBodyId);

                // 遍历已做集合 存在相等则加分 设置用户答题
                for (ItemIdOptionBody doneItemBody : questionDoneList) {
                    String option = doneItemBody.getValue();
                    // 题目已做
                    if (allItemBodyId.equals(doneItemBody.getId())) {
                        allItemBody.setValue(option);
                        itemPaperDao.setOption(option);
                        // 判断题目类型
                        score = getScoreAndStore(single, multiple, judge, practical, score, singleQuestionList,
                                multipleQuestionList, judgeQuestionList, practicalQuestionList, itemPaperDao, option);
                    }
                }
                // 正确已添加的不重复添加
                if (ObjectUtil.isEmpty(allItemBody.getValue())) {
                    // 未做
                    score = getScoreAndStore(single, multiple, judge, practical, score, singleQuestionList,
                            multipleQuestionList, judgeQuestionList, practicalQuestionList, itemPaperDao, "null");
                }

            }

            // 更新分数
            practiceRecordDO.setScore(score);
            int questionNum = questionDoneList.size();
            practiceRecordDO.setCompleteNum(questionNum);
            // 最新答题记录
            practiceRecordDO.setQuestionAnswerList(JSON.toJSONString(questionAllList));

            // 考试时间已到 或 答题数等于题目数 则为已完成不可继续答题
            //TestPaperTemplateDO testPaperTemplateDetail = resourceMapper.getTestPaperTemplateDetail(practiceRecordBody.getPaperId());
            // TODO 完成时间判断
            if (practiceRecord.getState() == 0) {
                if (Constants.DEFAULT_END_TIME.equals(examTime) || practiceRecordDO.getCompleteNum() == questionAllList.size()) {
                    // 如果是退出 则状态为暂存 不为完成
                    if (practiceRecordBody.getIsSubmit() == 1) {
                        practiceRecordDO.setState(1);
                    } else {
                        if (practiceRecord.getState() != 1) {
                            practiceRecordDO.setState(0);
                        }
                    }
                } else {
                    if (practiceRecord.getState() != 1) {
                        practiceRecordDO.setState(0);
                    }
                }
            } else {
                practiceRecordDO.setState(practiceRecord.getState());
            }

            // 提交时更新练习记录的 分数 做题数 答题集合 最新做题时间 完成状态
            practiceRecordDO.setExaminationTime(examTime);
            boolean b = resourceMapper.updatePracticeRecord(practiceRecordDO, practiceRecordBody.getPracticeRecordId());
            if (!b) return null;

        } else {
            PracticeRecordDO doneNothing = new PracticeRecordDO();

            if (Constants.DEFAULT_END_TIME.equals(examTime)) {
                doneNothing.setState(1);
                doneNothing.setScore(0);
            } else {
                doneNothing.setState(0);
                doneNothing.setScore(practiceRecord.getScore());
            }
            doneNothing.setExaminationTime(DateUtils.getHourMinuteSecond(practiceRecordBody.getExaminationTime()));
            doneNothing.setLatestPracticeTime(DateUtils.getTime());
            resourceMapper.updatePracticeRecordDoNothing(doneNothing, practiceRecordBody.getPracticeRecordId());
        }

        // 返回试卷做题详情
        ExamPaperVO examPaperVO = new ExamPaperVO();
        examPaperVO.setTemplateId(practiceRecordBody.getPaperId());
        examPaperVO.setTemplateName(practiceRecordBody.getPaperTitle());
        examPaperVO.setScore(score);
        examPaperVO.setSingle(singleQuestionList);
        examPaperVO.setMultiple(multipleQuestionList);
        examPaperVO.setJudge(judgeQuestionList);
        examPaperVO.setPractical(practicalQuestionList);
        examPaperVO.setPracticeRecordId(practiceRecordBody.getPracticeRecordId());
        return examPaperVO;
    }

    @Override
    public ApiResult submitPaper2(PracticeRecordBody practiceRecordBody) {
        // 退出保存试卷
        if (practiceRecordBody.getIsSubmit() == 0) {
            return ApiResult.success(savePaper(practiceRecordBody));
        }

        //String 转List
        JSONArray answerJson = JSON.parseArray(practiceRecordBody.getQuestionAnswerList());
        List<ItemIdOptionBody> questionDoneList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);

        if (answerJson.size() == 0) {
            return ApiResult.fail("请至少完成一题再交卷!");
        }

        UserDO user = JWTUtil.getUser();
        Long userId = user.getId();
        String name = user.getName();

        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.eq("id", userId);
        UserDO one = userServer.getOne(userDOQueryWrapper);

        Long classId;
        if (one.getType() == 0) {
            // 根据用户id获取 班级id
            classId = classMapper.getUserClassId(userId).getClassId();
        } else {
            classId = null;
        }

        int score = 0;
        ArrayList<ItemPaperDao> singleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> multipleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> judgeQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> allQuestionsList = new ArrayList<>();
        PracticeRecordDO practiceRecordDO = new PracticeRecordDO();
        practiceRecordDO.setId(practiceRecordBody.getPracticeRecordId());
        PracticeRecordDO practiceRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());

        // 总题目集合 questionALLList   已做题目集合 questionVOList
        String allQuestionList = practiceRecord.getQuestionAnswerList();
        List<ItemIdOptionBody> questionAllList = JSONArray.parseArray((JSON.parseArray(allQuestionList)).toJSONString(), ItemIdOptionBody.class);

        String examTime = DateUtils.getHourMinuteSecond(practiceRecordBody.getExaminationTime());
        // 用户答题集合不为为空
//        int single = 0, multiple = 0, judge = 0, practical = 0;
//        // 获取各题目分值
//        List<TemplateDetailsDO> templateDetailList = resourceMapper.getTemplateDetail(practiceRecord.getPaperId(),
//                0);
//        for (TemplateDetailsDO templateDetailsDO : templateDetailList) {
//            // 获取总题目数量
//            if (0 == templateDetailsDO.getType()) {
//                single = templateDetailsDO.getScore();
//            } else if (1 == templateDetailsDO.getType()) {
//                multiple = templateDetailsDO.getScore();
//            } else if (2 == templateDetailsDO.getType()) {
//                judge = templateDetailsDO.getScore();
//            } else if (3 == templateDetailsDO.getType()) {
//                practical = templateDetailsDO.getScore();
//            }
//        }

        // 练习记录字段
        BeanUtils.copyProperties(practiceRecordBody, practiceRecordDO);
        practiceRecordDO.setPaperId(practiceRecord.getPaperId());
        practiceRecordDO.setClassId(classId);
        practiceRecordDO.setUserId(userId);
        practiceRecordDO.setStudentName(name);
        practiceRecordDO.setLatestPracticeTime(DateUtils.getTime());
        practiceRecordDO.setExaminationTime(examTime);

        String classname = classMapper.getClassById(classId);
        // 遍历总题目集合 返回试卷题目答案 计算分值 先小后大
        for (ItemIdOptionBody allItemBody : questionAllList) {
            Long allItemBodyId = allItemBody.getId();
            // 获取题目详情
            ItemPaperDao itemPaperDao = resourceMapper.questionDetail(allItemBodyId);
            itemPaperDao.setOption(null);

            // 遍历已做集合 存在相等则加分 设置用户答题
            for (ItemIdOptionBody doneItemBody : questionDoneList) {
                String option = doneItemBody.getValue();
                // 题目已做
                if (allItemBodyId.equals(doneItemBody.getId())) {
                    itemPaperDao.setOption(option);
                    allItemBody.setValue(option);
                    //  已做集合获取分数 itemPaperDao practiceRecordBody
                    score = getScore(itemPaperDao, practiceRecordDO, score, singleQuestionList, multipleQuestionList
                            , judgeQuestionList, allQuestionsList);
                }
            }

            // 记录错题集
            if (ObjectUtil.notEqual(itemPaperDao.getRightKey().replaceAll(";;", ""), itemPaperDao.getOption()) ||
                    ObjectUtil.isEmpty(allItemBody.getValue())) {
                addErrorBook(1, userId, classId, classname, itemPaperDao);
            } else {
                addErrorBook(0, userId, classId, classname, itemPaperDao);
            }
        }

//
//
//        questionAllList.forEach(itemIdOptionBody -> {
//            ItemPaperDao itemPaperDao = resourceMapper.questionDetail(itemIdOptionBody.getId());
//            itemPaperDao.setOption(itemIdOptionBody.getValue());
//
//        });

        // 更新分数
        practiceRecordDO.setScore(score);
        int questionNum = questionDoneList.size();
        practiceRecordDO.setCompleteNum(questionNum);
        // 最新答题记录
        practiceRecordDO.setQuestionAnswerList(JSON.toJSONString(questionAllList));

        // 练习记录
//        PracticeRecordDO existPracticeRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());
        // 防止前端重复提交bug
//        if (existPracticeRecord.getState() != 1 ) {
        // 默认完成
        practiceRecordDO.setState(1);
        // 提交时更新练习记录的 分数 做题数 答题集合 最新做题时间 完成状态
        practiceRecordDO.setExaminationTime(examTime);
        boolean b = resourceMapper.updatePracticeRecord(practiceRecordDO, practiceRecordBody.getPracticeRecordId());
        if (!b) return ApiResult.fail("交卷失败！");
//        }

        // 返回试卷做题详情
        ExamPaperVO examPaperVO = new ExamPaperVO();
        examPaperVO.setTemplateId(practiceRecordBody.getPaperId());
        examPaperVO.setTemplateName(practiceRecordBody.getPaperTitle());
        examPaperVO.setScore(score);
        examPaperVO.setSingle(singleQuestionList);
        examPaperVO.setMultiple(multipleQuestionList);
        examPaperVO.setJudge(judgeQuestionList);
//        examPaperVO.setPractical(practicalQuestionList);
        examPaperVO.setPracticeRecordId(practiceRecordBody.getPracticeRecordId());
        return ApiResult.success(examPaperVO);
    }

    /**
     * 退出保存练习记录
     *
     * @param practiceRecordBody
     * @return
     * @throws ParseException
     */
    private Boolean savePaper(PracticeRecordBody practiceRecordBody) {
        // 获取做题人信息
        UserDO user = JWTUtil.getUser();
        Long userId = user.getId();
        String name = user.getName();

        Long classId = classMapper.getUserClassId(userId).getClassId();

        PracticeRecordDO practiceRecordDO = new PracticeRecordDO();
        practiceRecordDO.setId(practiceRecordBody.getPracticeRecordId());

        // 练习记录
        PracticeRecordDO practiceRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());

        //解析已做题目集合 String 转List
        JSONArray answerJson = JSON.parseArray(practiceRecordBody.getQuestionAnswerList());
        List<ItemIdOptionBody> questionDoneList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);

        // 为做题退出
        if (ObjectUtil.isNull(practiceRecord.getQuestionAnswerList())) {
            return true;
        }
        // 总题目集合 questionALLList
        String allQuestionList = practiceRecord.getQuestionAnswerList();
        List<ItemIdOptionBody> questionAllList = JSONArray.parseArray((JSON.parseArray(allQuestionList)).toJSONString(), ItemIdOptionBody.class);

        // 遍历总题目集合 更新做题信息
        for (ItemIdOptionBody allItemBody : questionAllList) {
            Long allItemBodyId = allItemBody.getId();

            // 遍历已做集合 存在相等则更新答题
            for (ItemIdOptionBody doneItemBody : questionDoneList) {
                String option = doneItemBody.getValue();
                // 题目已做
                if (allItemBodyId.equals(doneItemBody.getId())) {
                    allItemBody.setValue(option);
                }
            }
        }

        String examTime = DateUtils.getHourMinuteSecond(practiceRecordBody.getExaminationTime());
        // 练习记录字段 提交时更新练习记录的 分数 做题数 答题集合 最新做题时间 完成状态 更新做题数
        BeanUtils.copyProperties(practiceRecordBody, practiceRecordDO);
        practiceRecordDO.setQuestionAnswerList(JSON.toJSONString(questionAllList));
        System.out.println(JSON.toJSONString(questionAllList));
        practiceRecordDO.setCompleteNum(questionDoneList.size());
        practiceRecordDO.setPaperId(practiceRecordBody.getPaperId());
        practiceRecordDO.setClassId(classId);
        practiceRecordDO.setUserId(userId);
        practiceRecordDO.setStudentName(name);
        practiceRecordDO.setLatestPracticeTime(DateUtils.getTime());
        practiceRecordDO.setExaminationTime(examTime);
        practiceRecordDO.setState(0);

        boolean b = resourceMapper.updatePracticeRecord(practiceRecordDO, practiceRecordBody.getPracticeRecordId());
        return b;
    }

    /**
     * 根据知识点id 试卷id 查询试卷详情 记分
     */
    private int getScore(ItemPaperDao itemPaperDao, PracticeRecordDO practiceRecordDO,
                         int score, ArrayList<ItemPaperDao> singleQuestionList, ArrayList<ItemPaperDao> multipleQuestionList,
                         ArrayList<ItemPaperDao> judgeQuestionList, ArrayList<ItemPaperDao> allQuestionsList) {
        String option = itemPaperDao.getOption().replaceAll(";;", "");
        itemPaperDao.setOption(option);
        // 题目已做
        if (0 == itemPaperDao.getTopicTypes()) {
            // 答题正确分数增加
            if (option.equals(itemPaperDao.getRightKey())) {
                // 查分
                QueryWrapper<TemplateDetailsDO> wrapper = new QueryWrapper<>();
                wrapper.eq("tptemplate_id", practiceRecordDO.getPaperId());
                wrapper.eq("kpoints_id", itemPaperDao.getKpointsId());
                wrapper.eq("type", 0);
                TemplateDetailsDO templateDetailsDO = templateDetailsMapper.selectOne(wrapper);
                score += templateDetailsDO.getScore();
            }
            singleQuestionList.add(itemPaperDao);
            allQuestionsList.add(itemPaperDao);
        } else if (1 == itemPaperDao.getTopicTypes()) {
            if (option.equals(StrUtil.removeAll(itemPaperDao.getRightKey(), ";;"))) {
                QueryWrapper<TemplateDetailsDO> wrapper = new QueryWrapper<>();
                wrapper.eq("tptemplate_id", practiceRecordDO.getPaperId());
                wrapper.eq("kpoints_id", itemPaperDao.getKpointsId());
                wrapper.eq("type", 1);
                TemplateDetailsDO templateDetailsDO = templateDetailsMapper.selectOne(wrapper);
                score += templateDetailsDO.getScore();
            }
            multipleQuestionList.add(itemPaperDao);
            allQuestionsList.add(itemPaperDao);
        } else if (2 == itemPaperDao.getTopicTypes()) {
            if (option.equals(itemPaperDao.getRightKey())) {
                QueryWrapper<TemplateDetailsDO> wrapper = new QueryWrapper<>();
                wrapper.eq("tptemplate_id", practiceRecordDO.getPaperId());
                wrapper.eq("kpoints_id", itemPaperDao.getKpointsId());
                wrapper.eq("type", 2);
                TemplateDetailsDO templateDetailsDO = templateDetailsMapper.selectOne(wrapper);
                score += templateDetailsDO.getScore();
            }
            judgeQuestionList.add(itemPaperDao);
            allQuestionsList.add(itemPaperDao);
        }
//        else if (3 == itemPaperDao.getTopicTypes()) {
//            if (option.equals(itemPaperDao.getRightKey())) {
//                QueryWrapper<TemplateDetailsDO> wrapper = new QueryWrapper<>();
//                wrapper.eq("tptemplate_id", practiceRecordDO.getPaperId());
//                wrapper.eq("kpoints_id", itemPaperDao.getKpointsId());
//                wrapper.eq("type", 3);
//                TemplateDetailsDO templateDetailsDO = templateDetailsMapper.selectOne(wrapper);
//                score += templateDetailsDO.getScore();
//            }
//        }
        return score;
    }

    /**
     * 新增到错题集 先添加所有错误的 再添加所有交卷后选择项为空的
     *
     * @param isRight      0正确 1错误
     * @param userId
     * @param classId
     * @param classname
     * @param itemPaperDao
     * @return
     */
    private Boolean addErrorBook(Integer isRight, Long userId, Long classId, String classname, ItemPaperDao itemPaperDao) {
        ErrorBookDO odlErrorBookDO = errorBookService.getOne(new QueryWrapper<ErrorBookDO>()
                .eq("user_id", userId)
                .eq("topic_id", itemPaperDao.getId()));

        // 修改
        if (ObjectUtil.isNotNull(odlErrorBookDO)) {
            // 错误
            if (isRight == 1) {
                odlErrorBookDO.setAnswerCount(odlErrorBookDO.getAnswerCount() + 1);
                odlErrorBookDO.setWrongCount(odlErrorBookDO.getWrongCount() + 1);
                odlErrorBookDO.setUserOption(itemPaperDao.getOption());
                odlErrorBookDO.setStatus(isRight);
                odlErrorBookDO.setCreateDate(LocalDateTime.now());
                return errorBookService.updateById(odlErrorBookDO);
            }

            // 正确
            odlErrorBookDO.setAnswerCount(odlErrorBookDO.getAnswerCount() + 1);
            odlErrorBookDO.setStatus(isRight);
            return errorBookService.updateById(odlErrorBookDO);
        }

        //新增
        ErrorBookDO errorBookDO = new ErrorBookDO();
        errorBookDO.setCreateDate(LocalDateTime.now());
        errorBookDO.setUserId(userId);
        errorBookDO.setClassId(classId);
        errorBookDO.setClassname(classname);
        errorBookDO.setTopicId(itemPaperDao.getId());
        errorBookDO.setTopicType(itemPaperDao.getTopicTypes());
        errorBookDO.setUserOption(itemPaperDao.getOption());
        errorBookDO.setTopicContent(itemPaperDao.getTopicContent());
        errorBookDO.setAnswerCount(1);

        // 正确
        if (isRight == 0) {
            errorBookDO.setStatus(isRight);
            errorBookDO.setWrongCount(0);
            return errorBookService.save(errorBookDO);
        }

        errorBookDO.setUserOption(itemPaperDao.getOption());
        errorBookDO.setWrongCount(1);
        errorBookDO.setStatus(isRight);

        return errorBookService.save(errorBookDO);
    }


    private int getScoreAndStore(int single, int multiple, int judge, int practical, int score, ArrayList<ItemPaperDao> singleQuestionList,
                                 ArrayList<ItemPaperDao> multipleQuestionList, ArrayList<ItemPaperDao> judgeQuestionList,
                                 ArrayList<ItemPaperDao> practicalQuestionList, ItemPaperDao itemPaperDao, String option) {
        if (0 == itemPaperDao.getTopicTypes()) {
            // 答题正确分数增加
            if (option.equals(itemPaperDao.getRightKey())) {
                score += single;
            }
            singleQuestionList.add(itemPaperDao);
        } else if (1 == itemPaperDao.getTopicTypes()) {
            // 多选去除多余分号
            if (option.equals(StrUtil.removeAll(itemPaperDao.getRightKey(), ";;"))) {
                score += multiple;
            }
            multipleQuestionList.add(itemPaperDao);
        } else if (2 == itemPaperDao.getTopicTypes()) {
            if (option.equals(itemPaperDao.getRightKey())) {
                score += judge;
            }
            judgeQuestionList.add(itemPaperDao);
        } else if (3 == itemPaperDao.getTopicTypes()) {
            if (option.equals(itemPaperDao.getRightKey())) {
                score += practical;
            }
            practicalQuestionList.add(itemPaperDao);
        }
        return score;
    }


    /**
     * 根据练习id获取答题记录 获取题目集合 返回已做(返回已做选项)和未做
     * 继续答题
     *
     * @param practiceRecordId
     * @return
     */
    @Override
    public ContinueExamVO continueExam(Long practiceRecordId) {
        PracticeRecordDO practiceRecordDO = resourceMapper.getContinuePracticeRecord(practiceRecordId);
        String questionAnswerList = practiceRecordDO.getQuestionAnswerList();

        // 遍历问题集合 返回题目集合
        JSONArray objects = JSON.parseArray(questionAnswerList);
        List<ItemIdOptionBody> questionList = JSONArray.parseArray(objects.toJSONString(), ItemIdOptionBody.class);

        ArrayList<ItemPaperDao> singleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> multipleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> judgeQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> practicalQuestionList = new ArrayList<>();

        for (ItemIdOptionBody itemIdOptionBody : questionList) {
            // 根据id查询题目 分类存储
            ItemPaperDao itemPaperDao = resourceMapper.questionDetail(itemIdOptionBody.getId());
            // 存入用户答题
            itemPaperDao.setOption(itemIdOptionBody.getValue());
            // 正确答案和题目解析不传
            itemPaperDao.setRightKey("");
            itemPaperDao.setTopicAnalysis("");

            // 判断题目类型
            if (0 == itemPaperDao.getTopicTypes()) {
                singleQuestionList.add(itemPaperDao);
            } else if (1 == itemPaperDao.getTopicTypes()) {
                multipleQuestionList.add(itemPaperDao);
            } else if (2 == itemPaperDao.getTopicTypes()) {
                judgeQuestionList.add(itemPaperDao);
            } else if (3 == itemPaperDao.getTopicTypes()) {
                practicalQuestionList.add(itemPaperDao);
            }
        }
        // 时间格式校验
        String examTime = practiceRecordDO.getExaminationTime();
        SimpleDateFormat sdf = new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
        try {
            sdf.parse(examTime);
            examTime = DateUtils.getHourMinuteSecond(practiceRecordDO.getExaminationTime());
        } catch (ParseException e) {
        }
        return new ContinueExamVO(examTime, practiceRecordDO.getPaperTitle(), singleQuestionList, multipleQuestionList, judgeQuestionList, practicalQuestionList);
    }

    /**
     * @auther: ak
     * @Description 重新练习 读取练习记录 清除已做value 状态为未做
     * @param:
     * @return:
     * @date: 2024/5/10 13:38
     */
    public PaperDetailVo redoPractice(Long practiceRecordId) {

        PracticeRecordDO practiceRecordDO = resourceMapper.getContinuePracticeRecord(practiceRecordId);
        if (practiceRecordDO.getState() == 0) {
            return null;
        }

        // 转Json
        List<ItemIdOptionBody> itemIdOptionBodies =
                JSONArray.parseArray(practiceRecordDO.getQuestionAnswerList(), ItemIdOptionBody.class);

        ArrayList<ExaminationQuestionVO> singleQuestionList = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> multipleQuestionList = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> judgeQuestionList = new ArrayList<>();
        ArrayList<ExaminationQuestionVO> practicalQuestionList = new ArrayList<>();

        ArrayList<ItemIdOptionBody> allQuestionList = new ArrayList<>();
        // 遍历返回题目集合并清除已做
        for (ItemIdOptionBody itemIdOptionBody : itemIdOptionBodies) {
            ItemIdOptionBody newItemBody = new ItemIdOptionBody(itemIdOptionBody.getId(), "");
            allQuestionList.add(newItemBody);

            ItemPaperDao itemPaperDao = resourceMapper.questionDetail(itemIdOptionBody.getId());
            ExaminationQuestionVO examinationQuestionVO = new ExaminationQuestionVO();
            BeanUtils.copyProperties(itemPaperDao, examinationQuestionVO);

            // 判断题目类型
            if (0 == itemPaperDao.getTopicTypes()) {
                singleQuestionList.add(examinationQuestionVO);
            } else if (1 == itemPaperDao.getTopicTypes()) {
                multipleQuestionList.add(examinationQuestionVO);
            } else if (2 == itemPaperDao.getTopicTypes()) {
                judgeQuestionList.add(examinationQuestionVO);
            } else if (3 == itemPaperDao.getTopicTypes()) {
                practicalQuestionList.add(examinationQuestionVO);
            }
        }

        TestPaperTemplateDO templateDetail = resourceMapper.getTestPaperTemplateDetail(practiceRecordDO.getPaperId());
        String duration = templateDetail.getDuration() + ".00";
        //重新生成练习记录
        //  userId classId templateId paperTitle studentName completeNum latestPracticeTime score level examinationTime answerList state
        EventResourcePracticeRecordDO newPracticeRecordDO = new EventResourcePracticeRecordDO();
        BeanUtils.copyProperties(practiceRecordDO, newPracticeRecordDO);
        newPracticeRecordDO.setCompleteNum(0);
        newPracticeRecordDO.setLatestPracticeTime(DateUtils.getTime());
        newPracticeRecordDO.setExaminationTime(duration);
        newPracticeRecordDO.setState(0);
        newPracticeRecordDO.setScore(0);
        newPracticeRecordDO.setAnswerList(JSON.toJSONString(allQuestionList));
        newPracticeRecordDO.setTemplateId(practiceRecordDO.getPaperId());
        Long aLong = resourceMapper.savePracticeRecord(newPracticeRecordDO);

        // 返回试卷做题详情
        return new PaperDetailVo(newPracticeRecordDO.getId(), newPracticeRecordDO.getPaperTitle(), duration,
                singleQuestionList, multipleQuestionList, judgeQuestionList, practicalQuestionList);
    }


    /**
     * 获取所有赛项资源
     *
     * @return
     */
    @Override
    public List<EventResourceAllocationDO> evens() {
        return resourceMapper.evens();
    }

    /**
     * 只做更新
     *
     * @param practiceRecordBody
     * @return
     */
    @Override
    public boolean update(PracticeRecordBody practiceRecordBody) {
        PracticeRecordDO practiceRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());

        //String 转List
        JSONArray answerJson = JSON.parseArray(practiceRecordBody.getQuestionAnswerList());
        List<ItemIdOptionBody> questionDoneList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);

        // 总题目集合 questionALLList   已做题目集合 questionVOList
        String allQuestionList = practiceRecord.getQuestionAnswerList();
        List<ItemIdOptionBody> questionAllList = JSONArray.parseArray((JSON.parseArray(allQuestionList)).toJSONString(), ItemIdOptionBody.class);

        // 用户答题集合不为为空
        if (ObjectUtil.isNotEmpty(questionDoneList)) {
            // 获取各题目分值
            // 遍历已做集合 返回试卷题目答案 计算分值 先小后大
            for (ItemIdOptionBody allItemBody : questionAllList) {
                Long allItemBodyId = allItemBody.getId();
                // 获取题目详情
                ItemPaperDao itemPaperDao = resourceMapper.questionDetail(allItemBodyId);

                // 遍历总题目集合 存在相等则加分 设置用户答题
                for (ItemIdOptionBody doneItemBody : questionDoneList) {
                    String option = doneItemBody.getValue();
                    // 题目已做
                    if (allItemBodyId.equals(doneItemBody.getId())) {
                        allItemBody.setValue(option);
                        itemPaperDao.setOption(option);
                    }
                }
            }
        }
        // 最新答题记录 最近做题时间 考试用时
        practiceRecord.setQuestionAnswerList(JSON.toJSONString(questionAllList));
        practiceRecord.setLatestPracticeTime(DateUtils.getTime());
        practiceRecord.setExaminationTime(practiceRecordBody.getExaminationTime());
        practiceRecord.setCompleteNum(questionDoneList.size());
        boolean b = resourceMapper.updatePracticeRecord(practiceRecord, practiceRecordBody.getPracticeRecordId());
        return b;
    }

    @Override
    public ExamPaperVO teacherExamPaperDetail(PracticeRecordBody practiceRecordBody) {


        int score = 0;
        ArrayList<ItemPaperDao> singleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> multipleQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> judgeQuestionList = new ArrayList<>();
        ArrayList<ItemPaperDao> practicalQuestionList = new ArrayList<>();

        PracticeRecordDO practiceRecord = resourceMapper.getContinuePracticeRecord(practiceRecordBody.getPracticeRecordId());

        // 总题目集合
        JSONArray answerJson = JSON.parseArray(practiceRecordBody.getQuestionAnswerList());
        List<ItemIdOptionBody> allQuestionList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);

        int single = 0, multiple = 0, judge = 0, practical = 0;
        // 获取各题目分值
        List<TemplateDetailsDO> templateDetailList = resourceMapper.getTemplateDetail(practiceRecordBody.getPaperId(),
                0);
        for (TemplateDetailsDO templateDetailsDO : templateDetailList) {
            // 获取总题目数量
            if (0 == templateDetailsDO.getType()) {
                single = templateDetailsDO.getScore();
            } else if (1 == templateDetailsDO.getType()) {
                multiple = templateDetailsDO.getScore();
            } else if (2 == templateDetailsDO.getType()) {
                judge = templateDetailsDO.getScore();
            } else if (3 == templateDetailsDO.getType()) {
                practical = templateDetailsDO.getScore();
            }
        }


        // 遍历已做集合 返回试卷题目答案 计算分值 先小后大
        for (ItemIdOptionBody allItemBody : allQuestionList) {
            Long allItemBodyId = allItemBody.getId();
            // 获取题目详情
            ItemPaperDao itemPaperDao = resourceMapper.questionDetail(allItemBodyId);

            // 判断题目类型
            if (0 == itemPaperDao.getTopicTypes()) {
                singleQuestionList.add(itemPaperDao);
            } else if (1 == itemPaperDao.getTopicTypes()) {
                multipleQuestionList.add(itemPaperDao);
            } else if (2 == itemPaperDao.getTopicTypes()) {
                judgeQuestionList.add(itemPaperDao);
            } else if (3 == itemPaperDao.getTopicTypes()) {
                practicalQuestionList.add(itemPaperDao);
            }
        }

        // 返回试卷做题详情
        ExamPaperVO examPaperVO = new ExamPaperVO();
        examPaperVO.setTemplateId(practiceRecordBody.getPaperId());
        examPaperVO.setTemplateName(practiceRecordBody.getPaperTitle());
        examPaperVO.setScore(score);
        examPaperVO.setSingle(singleQuestionList);
        examPaperVO.setMultiple(multipleQuestionList);
        examPaperVO.setJudge(judgeQuestionList);
        examPaperVO.setPractical(practicalQuestionList);
        examPaperVO.setPracticeRecordId(practiceRecordBody.getPracticeRecordId());
        return examPaperVO;
    }

    @Override
    public TitleListVO getAllocationTitleList() {
        List<TitleVO> allocationTitleList = resourceMapper.getAllocationTitleList();

        ArrayList<String> resourceTitle = new ArrayList<>();
        ArrayList<String> courseTitle = new ArrayList<>();
        ArrayList<String> onePlusXTitle = new ArrayList<>();
        ArrayList<String> skillTitle = new ArrayList<>();
        ArrayList<String> industryTitle = new ArrayList<>();

        for (TitleVO titleVO : allocationTitleList) {
            if (titleVO.getEventMoId().equals(Constants.EVENTMOID_COURSE)) {
                courseTitle.add(titleVO.getEventTitle());
            } else if (titleVO.getEventMoId().equals(Constants.EVENTMOID_SECTOR)) {
                industryTitle.add(titleVO.getEventTitle());
            } else if (titleVO.getEventMoId().equals(Constants.EVENTMOID_COMPETITION)) {
                resourceTitle.add(titleVO.getEventTitle());
            } else if (titleVO.getEventMoId().equals(Constants.EVENTMOID_SKILLCULTIVATE)) {
                skillTitle.add(titleVO.getEventTitle());
            } else if (titleVO.getEventMoId().equals(Constants.EVENTMOID_ONEPLUSXCERTIFICATES)) {
                onePlusXTitle.add(titleVO.getEventTitle());
            }
        }

        return new TitleListVO(courseTitle, resourceTitle, onePlusXTitle, skillTitle, industryTitle);
    }

    @Override
    public boolean saveOrUpdateCaseRecord(CaseBody caseBody) {
        UserDO user = JWTUtil.getUser();
        Long existRecord = resourceMapper.isExistCaseRecord(user.getId(), caseBody.getPaperTitle());
        boolean success = true;
        if (ObjectUtil.isNull(existRecord)) {
            EventResourcePracticeRecordDO eventResourcePracticeRecordDO = new EventResourcePracticeRecordDO();
            // 新增
            BeanUtils.copyProperties(caseBody, eventResourcePracticeRecordDO);
            eventResourcePracticeRecordDO.setLatestPracticeTime(DateUtils.getTime());
            eventResourcePracticeRecordDO.setState(1);
            eventResourcePracticeRecordDO.setUserId(user.getId());
            StuClassDO stuClassDO = classMapper.getUserClassId(user.getId());
            eventResourcePracticeRecordDO.setClassId(stuClassDO.getClassId());
            UserDO userDO = userServer.getById(user.getId());
            eventResourcePracticeRecordDO.setStudentName(userDO.getName());
            // 案例分析题题数
            eventResourcePracticeRecordDO.setCompleteNum(1);
            Long aLong = resourceMapper.savePracticeRecord(eventResourcePracticeRecordDO);
            success = aLong == null ? false : true;
        } else {
            // 更新时间
            boolean b = resourceMapper.updateCasePracticeRecord(DateUtils.getTime(), existRecord);
            success = b;
        }

        return success;
    }
}
